<?php
/**
 * (jobs) 创建采购单
 */
namespace App\Jobs\Purchase;

use App\Util\SerialNo;
use App\Models\Sys\Logs;
use App\Models\Basics\Supplier;
use App\Models\Product\ProductSupplier;
use App\Models\Purchase\PurchaseOrder;
use App\Models\Stocking\StockingApply;
use App\Models\Stocking\StockingApplyDetail;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\DB;
class CreatePurchase implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $data;

    protected $userId;

    /**
     * CreatePurchase constructor.
     * @param $data
     * @param $userId
     */
    public function __construct($data,$userId)
    {
        $this->data = $data;
        $this->userId = $userId;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try{
            DB::beginTransaction();
            foreach ($this->data as $supplierId => $_data){
                $purchaseOrder = $purchaseOrderDetail = $purchaseStockingDetail = [];
                $purchaseOrder['purchase_no'] = SerialNo::getCGNo();
                $purchaseOrder['supplier_id'] = $supplierId;
                $purchaseOrder['settlement_method_id'] = $this->_getSettlementMethodId($supplierId); //结算方式
                foreach ($_data as $pSkuId => $item){
                    $price = $this->_getUnitPriceAndSupplierPrice($supplierId,$pSkuId); //sku价格和供应商价格
                    $purchaseOrderDetail[$pSkuId]['psku_id'] = $pSkuId;
                    $purchaseOrderDetail[$pSkuId]['supplier_price'] = $price['supplier_price'];
                    $purchaseOrderDetail[$pSkuId]['unit_price'] = $price['unit_price'];
                    $purchaseOrderDetail[$pSkuId]['apply_num'] = $item['apply_num'];
                    $purchaseOrderDetail[$pSkuId]['plan_num'] = $item['plan_num'];
                    $purchaseOrderDetail[$pSkuId]['order_num'] = $item['plan_num'];
                    unset($item['apply_num']);
                    unset($item['plan_num']);
                    foreach ($item as $applyDetailId => $_item){
                        $purchaseStockingDetail[$pSkuId][$applyDetailId]['apply_detail_id'] = $applyDetailId;
                        $purchaseStockingDetail[$pSkuId][$applyDetailId]['apply_num'] = $_item['apply_num'];
                        $purchaseStockingDetail[$pSkuId][$applyDetailId]['plan_num'] = $_item['plan_num'];
                    }
                }
                $purchaseOrder['pu_user_id'] = $this->userId;

                //采购单
                $purchaseOrderModel = PurchaseOrder::create($purchaseOrder);

                //采购单明细
                $purchaseOrderDetailModels = $purchaseOrderModel->order_detail()->createMany($purchaseOrderDetail);
                foreach ($purchaseOrderDetailModels as $purchaseOrderDetailModel){
                    $_purchaseStockingDetail = $purchaseStockingDetail[$purchaseOrderDetailModel->psku_id];
                    //采购备货明细
                    $purchaseOrderDetailModel->stocking_detail()->createMany($_purchaseStockingDetail);
                    foreach ($_purchaseStockingDetail as $applyDetailId => $__purchaseStockingDetail){
                        $this->_upPlanStatus($applyDetailId,$__purchaseStockingDetail['plan_num']);
                    }
                }
                Logs::logs('purchase',"创建采购单：$purchaseOrderModel->purchase_no",$purchaseOrderModel->id,$this->userId);
            }
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
        }
    }

    /**
     * 更新备货单计划状态
     * @param $applyDetailId
     * @param $planNum
     */
    private function _upPlanStatus($applyDetailId,$planNum){
        //备货单明细
        $sad = StockingApplyDetail::query()->find($applyDetailId);
        $sad->plan_num += $planNum;
        if($sad->plan_num >= $sad->apply_detail_num){
            $sad->plan_status = StockingApplyDetail::PLAN_STATUS_ALL; //完全计划
        }elseif($sad->plan_num > 0 && $sad->plan_num < $sad->apply_detail_num){
            $sad->plan_status = StockingApplyDetail::PLAN_STATUS_PART; //部分计划
        }else{
            $sad->plan_status = StockingApplyDetail::PLAN_STATUS_NO; //未计划
        }
        $sad->save();

        //备货单
        $detailPlanStatus = StockingApplyDetail::query()->where('stocking_no',$sad->stocking_no)->pluck('plan_status')->toArray();
        $planStatus = StockingApplyDetail::extractStatus($detailPlanStatus);
        $sa = StockingApply::query()->where('stocking_no',$sad->stocking_no)->first();
        $sa->plan_status = $planStatus;
        $sa->save();
    }

    /**
     * 获取结算方式
     * @param $supplierId
     * @return mixed
     */
    private function _getSettlementMethodId($supplierId){
        return Supplier::query()->where('id',$supplierId)->value('settlement_method_id');
    }

    /**
     * 获取供应商sku价格和供应商价格
     * @param $supplierId
     * @param $pSkuId
     * @return array
     */
    private function _getUnitPriceAndSupplierPrice($supplierId,$pSkuId){
         $re = ProductSupplier::query()
            ->where('supplier_id',$supplierId)
            ->where('psku_id',$pSkuId)
            ->first();
        return ['supplier_price' => $re->supplier_price ?? 0, 'unit_price' => $re->unit_price ?? 0];
    }
}
